package model

import (
	"bytes"
	"errors"
	"github.com/jmoiron/sqlx"
	"strings"
	"time"
)

// 监测结果信息
type Rt3dresults struct {
	ID                      int       `db:"ID"`                      //监测结果标识ID
	PointID                 int       `db:"Point_ID"`                //测点ID值
	Type                    int16     `db:"Type"`                    //监测类别
	Epoch                   time.Time `db:"Epoch"`                   //观测时间
	Description             string    `db:"Description"`             //备注
	North                   float64   `db:"North"`                   //北坐标
	East                    float64   `db:"East"`                    //东坐标
	Height                  float64   `db:"Height"`                  //高程
	State                   int16     `db:"State"`                   //状态
	CustomText1             string    `db:"CustomText1"`             //备注2
	CurrEastDisplacement    float64   `db:"CurrEastDisplacement"`    //当前变形量东
	CurrNorthDisplacement   float64   `db:"CurrNorthDisplacement"`   //当前变形量北
	CurrHeightDisplacement  float64   `db:"CurrHeightDisplacement"`  //当前变形量高
	TotalEastDisplacement   float64   `db:"TotalEastDisplacement"`   //累计变形量东
	TotalNorthDisplacement  float64   `db:"TotalNorthDisplacement"`  //累计变形量北
	TotalHeightDisplacement float64   `db:"TotalHeightDisplacement"` //累计变形量高
	D1M                     float64   `db:"D1M"`                     //预留
	D1CurrVelocity          float64   `db:"D1CurrVelocity"`          //预留速率
	D1CurrTimeDiff          float64   `db:"D1CurrTimeDiff"`          //预留时间差
	D1TotalVelocity         float64   `db:"D1TotalVelocity"`         //预留
	D1TotalTimeDiff         float64   `db:"D1TotalTimeDiff"`         //预留
	D2M                     float64   `db:"D2M"`                     //预留
	D2CurrVelocity          float64   `db:"D2CurrVelocity"`          //预留
	D2CurrTimeDiff          float64   `db:"D2CurrTimeDiff"`          //预留
	D2TotalVelocity         float64   `db:"D2TotalVelocity"`         //预留
	D2TotalTimeDiff         float64   `db:"D2TotalTimeDiff"`         //预留
	D3M                     float64   `db:"D3M"`                     //预留
	D3CurrVelocity          float64   `db:"D3CurrVelocity"`          //预留
	D3CurrTimeDiff          float64   `db:"D3CurrTimeDiff"`          //预留
	D3TotalVelocity         float64   `db:"D3TotalVelocity"`         //预留
	D3TotalTimeDiff         float64   `db:"D3TotalTimeDiff"`         //预留
}

// 根据【监测结果标识ID】查询【监测结果信息】表中是否存在相关记录
func (d *Rt3dresults) Exist(ID int) (bool, error) {
	rows, err := amp.Queryx("SELECT COUNT(0) Count FROM rt3dresults WHERE ID=?", ID)
	if err != nil {
		return false, err
	}
	defer rows.Close()
	count := 0
	if rows.Next() {
		err = rows.Scan(&count)
		if err != nil {
			return false, err
		}
		return count > 0, nil
	}
	return false, nil
}

// 插入单条记录到【监测结果信息】表中
func (d *Rt3dresults) Insert() (int64, error) {
	result, err := amp.Exec("INSERT INTO rt3dresults(Point_ID,Type,Epoch,Description,North,East,Height,State,CustomText1,CurrEastDisplacement,CurrNorthDisplacement,CurrHeightDisplacement,TotalEastDisplacement,TotalNorthDisplacement,TotalHeightDisplacement,D1M,D1CurrVelocity,D1CurrTimeDiff,D1TotalVelocity,D1TotalTimeDiff,D2M,D2CurrVelocity,D2CurrTimeDiff,D2TotalVelocity,D2TotalTimeDiff,D3M,D3CurrVelocity,D3CurrTimeDiff,D3TotalVelocity,D3TotalTimeDiff) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", d.PointID, d.Type, d.Epoch, d.Description, d.North, d.East, d.Height, d.State, d.CustomText1, d.CurrEastDisplacement, d.CurrNorthDisplacement, d.CurrHeightDisplacement, d.TotalEastDisplacement, d.TotalNorthDisplacement, d.TotalHeightDisplacement, d.D1M, d.D1CurrVelocity, d.D1CurrTimeDiff, d.D1TotalVelocity, d.D1TotalTimeDiff, d.D2M, d.D2CurrVelocity, d.D2CurrTimeDiff, d.D2TotalVelocity, d.D2TotalTimeDiff, d.D3M, d.D3CurrVelocity, d.D3CurrTimeDiff, d.D3TotalVelocity, d.D3TotalTimeDiff)
	if err != nil {
		return -1, err
	}
	return result.LastInsertId()
}

// 根据【监测结果标识ID】修改【监测结果信息】表的单条记录
func (d *Rt3dresults) Update() (bool, error) {
	result, err := amp.Exec("UPDATE rt3dresults SET Point_ID=?, Type=?, Epoch=?, Description=?, North=?, East=?, Height=?, State=?, CustomText1=?, CurrEastDisplacement=?, CurrNorthDisplacement=?, CurrHeightDisplacement=?, TotalEastDisplacement=?, TotalNorthDisplacement=?, TotalHeightDisplacement=?, D1M=?, D1CurrVelocity=?, D1CurrTimeDiff=?, D1TotalVelocity=?, D1TotalTimeDiff=?, D2M=?, D2CurrVelocity=?, D2CurrTimeDiff=?, D2TotalVelocity=?, D2TotalTimeDiff=?, D3M=?, D3CurrVelocity=?, D3CurrTimeDiff=?, D3TotalVelocity=?, D3TotalTimeDiff=? WHERE ID=?", d.PointID, d.Type, d.Epoch, d.Description, d.North, d.East, d.Height, d.State, d.CustomText1, d.CurrEastDisplacement, d.CurrNorthDisplacement, d.CurrHeightDisplacement, d.TotalEastDisplacement, d.TotalNorthDisplacement, d.TotalHeightDisplacement, d.D1M, d.D1CurrVelocity, d.D1CurrTimeDiff, d.D1TotalVelocity, d.D1TotalTimeDiff, d.D2M, d.D2CurrVelocity, d.D2CurrTimeDiff, d.D2TotalVelocity, d.D2TotalTimeDiff, d.D3M, d.D3CurrVelocity, d.D3CurrTimeDiff, d.D3TotalVelocity, d.D3TotalTimeDiff, d.ID)
	if err != nil {
		return false, err
	}
	affected, err := result.RowsAffected()
	if err != nil {
		return false, err
	}
	return affected > 0, nil
}

// 根据【监测结果标识ID】查询【监测结果信息】表中的单条记录
func (d *Rt3dresults) Get(ID int) (rt3dresults Rt3dresults, err error) {
	rows, err := amp.Queryx("SELECT ID, Point_ID, Type, Epoch, Description, North, East, Height, State, CustomText1, CurrEastDisplacement, CurrNorthDisplacement, CurrHeightDisplacement, TotalEastDisplacement, TotalNorthDisplacement, TotalHeightDisplacement, D1M, D1CurrVelocity, D1CurrTimeDiff, D1TotalVelocity, D1TotalTimeDiff, D2M, D2CurrVelocity, D2CurrTimeDiff, D2TotalVelocity, D2TotalTimeDiff, D3M, D3CurrVelocity, D3CurrTimeDiff, D3TotalVelocity, D3TotalTimeDiff FROM rt3dresults WHERE ID=?", ID)
	if err != nil {
		return rt3dresults, err
	}
	defer rows.Close()
	rt3dresultss, err := d._RowsToArray(rows)
	if err != nil {
		return rt3dresults, err
	}
	if len(rt3dresultss) <= 0 {
		return rt3dresults, err
	}
	return rt3dresultss[0], nil
}

// 根据【监测结果标识ID】数组查询【监测结果信息】表中的多条记录
func (d *Rt3dresults) GetIn(IDs []int) (rt3dresultss []Rt3dresults, err error) {
	if len(IDs) <= 0 {
		return rt3dresultss, errors.New("IDs is empty")
	}
	sqlStr := bytes.Buffer{}
	sqlStr.WriteString("SELECT ID, Point_ID, Type, Epoch, Description, North, East, Height, State, CustomText1, CurrEastDisplacement, CurrNorthDisplacement, CurrHeightDisplacement, TotalEastDisplacement, TotalNorthDisplacement, TotalHeightDisplacement, D1M, D1CurrVelocity, D1CurrTimeDiff, D1TotalVelocity, D1TotalTimeDiff, D2M, D2CurrVelocity, D2CurrTimeDiff, D2TotalVelocity, D2TotalTimeDiff, D3M, D3CurrVelocity, D3CurrTimeDiff, D3TotalVelocity, D3TotalTimeDiff FROM ")
	sqlStr.WriteString("rt3dresults")
	sqlStr.WriteString(" WHERE ID IN(")
	paramKeys := strings.Repeat("?,", len(IDs))
	sqlStr.WriteString(paramKeys[:len(paramKeys)-1])
	sqlStr.WriteString(")")
	var rows *sqlx.Rows
	vals := make([]interface{}, 0, len(IDs))
	for _, v := range IDs {
		vals = append(vals, v)
	}
	rows, err = amp.Queryx(sqlStr.String(), vals...)
	if err != nil {
		return rt3dresultss, err
	}
	defer rows.Close()
	return d._RowsToArray(rows)
}

// 查询【监测结果信息】表总记录数
func (d *Rt3dresults) GetRowCount() (count int, err error) {
	rows, err := amp.Queryx("SELECT COUNT(0) Count FROM rt3dresults")
	if err != nil {
		return -1, err
	}
	defer rows.Close()
	if rows.Next() {
		err = rows.Scan(&count)
		if err != nil {
			return -1, err
		}
		return count, nil
	}
	return -1, nil
}

// 分页查询【监测结果信息】表的记录
func (d *Rt3dresults) GetRowList(PageIndex, PageSize int) (rt3dresultss []Rt3dresults, err error) {
	rows, err := amp.Queryx("SELECT ID, Point_ID, Type, Epoch, Description, North, East, Height, State, CustomText1, CurrEastDisplacement, CurrNorthDisplacement, CurrHeightDisplacement, TotalEastDisplacement, TotalNorthDisplacement, TotalHeightDisplacement, D1M, D1CurrVelocity, D1CurrTimeDiff, D1TotalVelocity, D1TotalTimeDiff, D2M, D2CurrVelocity, D2CurrTimeDiff, D2TotalVelocity, D2TotalTimeDiff, D3M, D3CurrVelocity, D3CurrTimeDiff, D3TotalVelocity, D3TotalTimeDiff FROM rt3dresults LIMIT ?,?", (PageIndex-1)*PageSize, PageSize)
	if err != nil {
		return rt3dresultss, err
	}
	defer rows.Close()
	return d._RowsToArray(rows)
}

// 解析【监测结果信息】表记录
func (d *Rt3dresults) _RowsToArray(rows *sqlx.Rows) (models []Rt3dresults, err error) {
	for rows.Next() {
		mo := Rt3dresults{}
		err = rows.Scan(&mo.ID, &mo.PointID, &mo.Type, &mo.Epoch, &mo.Description, &mo.North, &mo.East, &mo.Height, &mo.State, &mo.CustomText1, &mo.CurrEastDisplacement, &mo.CurrNorthDisplacement, &mo.CurrHeightDisplacement, &mo.TotalEastDisplacement, &mo.TotalNorthDisplacement, &mo.TotalHeightDisplacement, &mo.D1M, &mo.D1CurrVelocity, &mo.D1CurrTimeDiff, &mo.D1TotalVelocity, &mo.D1TotalTimeDiff, &mo.D2M, &mo.D2CurrVelocity, &mo.D2CurrTimeDiff, &mo.D2TotalVelocity, &mo.D2TotalTimeDiff, &mo.D3M, &mo.D3CurrVelocity, &mo.D3CurrTimeDiff, &mo.D3TotalVelocity, &mo.D3TotalTimeDiff)
		if err != nil {
			return models, err
		}
		models = append(models, mo)
	}
	return models, err
}
